#include <iostream>
#include <set>
#include "rengine.h"


int count = 0;
std::map<Node*, int> labels;
std::set<Node*> visited;

void displayNfa(NFA nfa);
const static std::string rexp = "aa|b(b|c)*c";
int main() {
	std::string cutsom;
	std::cout << "enter re:" << std::endl;
	std::cout << ">";
	std::cin >> cutsom;
	std::cout << "RE: " << cutsom << std::endl;
	Rengine re(cutsom);
	NFA nfa = re.build();
	std::string input;
	while (true) {
		std::cout << ">";
		std::cin >> input;
		if (input == "!quit") {
			break;
		}
		std::cout << "\r" << "input:\"" << input <<"\"" << (re.match(input) ? "\t\tmatch" : "\t\tnot match") << std::endl;
	}
	
	//displayNfa(nfa);
	return 0;
}

void disNode(Node* node) {
	std::string nodeType;
	if (node->type == Node::START_TYPE) {
		nodeType.append("START");
	}
	else if (node->type == Node::END_TYPE) {
		nodeType.append("END");
	}
	if (labels.find(node) != labels.end()) {
		std::cout << "\r" << labels[node] << "|" << nodeType << "\t";

	}
	else {
		std::cout << "\r" << count << "|" << nodeType << "\t";
		labels[node] = count++;
	}
	visited.insert(node);
	const std::vector<Edge>& edges = node->getAdjEdges();
	if (edges.empty()) {
		std::cout << "NULL\n\r";
		return;
	}
	for (const Edge& e : edges) {
		char ch = '\0';
		if (e.type < 128) {
			ch = e.type;
		}
		else if (e.type == Edge::NULL_TYPE) {
			ch = '$';
		}
		if (labels.find(e.end) != labels.end()) {
			std::cout << ch << "-> " << labels[e.end] << "\n\t";

		}
		else {
			std::cout << ch << "-> " << count << "\n\t";
			labels[e.end] = count++;
		}
	}
	for (const Edge& e : edges) {
		if (visited.find(e.end) == visited.end())
			disNode(e.end);
	}
}
void displayNfa(NFA nfa) {
	disNode(nfa.start);
}